home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Games Collection 1 / software vault.zip / software vault / CDR10 / TGE129C.ZIP / SOURCE / 640X480.ASM < prev    next >
Assembly Source File  |  1993-08-20  |  49KB  |  2,513 lines

  1. ; 640x480x256 (requires register-compatible VGA+)
  2. ; Loadable driver for The Graphics Engine
  3. ; Copyright (c) 1993 by Matthew Hildebrand
  4. ; Turbo Assembler syntax
  5. ; Portions by John Bridges
  6.  
  7. IDEAL
  8. P486N            ; 386 code, but we want 486 alignment
  9. MODEL LARGE
  10.  
  11.  
  12. SCREEN_WIDE    =    640
  13. SCREEN_DEEP    =    480
  14. NUM_COLOURS    =    256
  15.  
  16.  
  17.         CODESEG
  18.         ORG    0
  19.  
  20. ;*** Signature
  21.             db    'TGE3'
  22. ;*** Non-I/O functions
  23. _initGraphics        dw    initGraphics        ; initGraphics
  24.             dw    ?
  25. _deInitGraphics        dw    0            ; deInitGraphics
  26.             dw    ?
  27. _setPaletteReg        dw    setPaletteReg        ; setPaletteReg
  28.             dw    ?
  29. _getPaletteReg        dw    getPaletteReg        ; getPaletteReg
  30.             dw    ?
  31. _setBlockPalette    dw    setBlockPalette        ; setBlockPalette
  32.             dw    ?
  33. _getBlockPalette    dw    getBlockPalette        ; getBlockPalette
  34.             dw    ?
  35. _colourCloseTo        dw    0            ; colourCloseTo
  36.             dw    ?
  37. _colourCloseToX        dw    0            ; colourCloseToX
  38.             dw    ?
  39. _imageSize        dw    0            ; imageSize
  40.             dw    ?
  41. _imageSizeDim        dw    0            ; imageSizeDim
  42.             dw    ?
  43. _setPage        dw    0            ; setPage (not implemented yet)
  44.             dw    ?
  45.  
  46. ;*** Currently active I/O functions (filled in by loadGraphDriver())
  47.             dd    20    DUP(?)
  48.  
  49. ;*** Input functions
  50. _getImage_scr        dw    0            ; getImage
  51.             dw    ?
  52. _getImage_mem        dw    0
  53.             dw    ?
  54. _getLine_scr        dw      getLine_scr              ; getLine
  55.             dw    ?
  56. _getLine_mem        dw    getLine_mem
  57.             dw    ?
  58. _getPixel_scr        dw    getPixel_scr        ; getPixel
  59.             dw    ?
  60. _getPixel_mem        dw    getPixel_mem
  61.             dw    ?
  62.  
  63. ;*** Output functions
  64. _putImage_scr_copy    dw    0            ; putImage
  65.             dw    ?
  66. _putImage_scr_and    dw    0
  67.             dw    ?
  68. _putImage_scr_not    dw    0
  69.             dw    ?
  70. _putImage_scr_or    dw    0
  71.             dw    ?
  72. _putImage_scr_xor    dw    0
  73.             dw    ?
  74. _putImage_mem_copy    dw    0
  75.             dw    ?
  76. _putImage_mem_and    dw    0
  77.             dw    ?
  78. _putImage_mem_not    dw    0
  79.             dw    ?
  80. _putImage_mem_or    dw    0
  81.             dw    ?
  82. _putImage_mem_xor    dw    0
  83.             dw    ?
  84. _putImageInv_scr_copy    dw    0            ; putImageInv
  85.             dw    ?
  86. _putImageInv_scr_and    dw    0
  87.             dw    ?
  88. _putImageInv_scr_not    dw      0
  89.             dw    ?
  90. _putImageInv_scr_or    dw      0
  91.             dw    ?
  92. _putImageInv_scr_xor    dw    0
  93.             dw    ?
  94. _putImageInv_mem_copy    dw    0
  95.             dw    ?
  96. _putImageInv_mem_and    dw    0
  97.             dw    ?
  98. _putImageInv_mem_not    dw    0
  99.             dw    ?
  100. _putImageInv_mem_or    dw    0
  101.             dw    ?
  102. _putImageInv_mem_xor    dw    0
  103.             dw    ?
  104. _putLine_scr_copy          dw    putLine_scr_copy    ; putLine
  105.             dw    ?
  106. _putLine_scr_and          dw      0
  107.             dw    ?
  108. _putLine_scr_not          dw      0
  109.             dw    ?
  110. _putLine_scr_or          dw      0
  111.             dw    ?
  112. _putLine_scr_xor          dw    0
  113.             dw    ?
  114. _putLine_mem_copy    dw      putLine_mem_copy
  115.             dw    ?
  116. _putLine_mem_and    dw      0
  117.             dw    ?
  118. _putLine_mem_not    dw      0
  119.             dw    ?
  120. _putLine_mem_or        dw      0
  121.             dw    ?
  122. _putLine_mem_xor    dw    0
  123.             dw    ?
  124. _putLineInv_scr_copy       dw    0            ; putLineInv
  125.             dw    ?
  126. _putLineInv_scr_and       dw    0
  127.             dw    ?
  128. _putLineInv_scr_not       dw    0
  129.             dw    ?
  130. _putLineInv_scr_or       dw    0
  131.             dw    ?
  132. _putLineInv_scr_xor       dw    0
  133.             dw    ?
  134. _putLineInv_mem_copy    dw    0
  135.             dw    ?
  136. _putLineInv_mem_and    dw    0
  137.             dw    ?
  138. _putLineInv_mem_not    dw    0
  139.             dw    ?
  140. _putLineInv_mem_or    dw    0
  141.             dw    ?
  142. _putLineInv_mem_xor    dw    0
  143.             dw    ?
  144. _putPixel_scr_copy    dw    putPixel_scr_copy    ; putPixel
  145.             dw    ?
  146. _putPixel_scr_and    dw      0
  147.             dw    ?
  148. _putPixel_scr_not    dw      0
  149.             dw    ?
  150. _putPixel_scr_or    dw      0
  151.             dw    ?
  152. _putPixel_scr_xor    dw    0
  153.             dw    ?
  154. _putPixel_mem_copy    dw    putPixel_mem_copy
  155.             dw    ?
  156. _putPixel_mem_and    dw      putPixel_mem_and
  157.             dw    ?
  158. _putPixel_mem_not    dw      putPixel_mem_not
  159.             dw    ?
  160. _putPixel_mem_or    dw      putPixel_mem_or
  161.             dw    ?
  162. _putPixel_mem_xor    dw    putPixel_mem_xor
  163.             dw    ?
  164. _line_scr_copy        dw    0            ; line
  165.             dw    ?
  166. _line_scr_and        dw      0
  167.             dw    ?
  168. _line_scr_not        dw      0
  169.             dw    ?
  170. _line_scr_or        dw      0
  171.             dw    ?
  172. _line_scr_xor        dw    0
  173.             dw    ?
  174. _line_mem_copy        dw    0
  175.             dw    ?
  176. _line_mem_and        dw    0
  177.             dw    ?
  178. _line_mem_not        dw    0
  179.             dw    ?
  180. _line_mem_or        dw    0
  181.             dw    ?
  182. _line_mem_xor        dw    0
  183.             dw    ?
  184. _horizLine_scr_copy    dw    horizLine_scr_copy      ; horizLine
  185.             dw    ?
  186. _horizLine_scr_and    dw      0
  187.             dw    ?
  188. _horizLine_scr_not    dw      0
  189.             dw    ?
  190. _horizLine_scr_or    dw      0
  191.             dw    ?
  192. _horizLine_scr_xor    dw    0
  193.             dw    ?
  194. _horizLine_mem_copy    dw    horizLine_mem_copy
  195.             dw    ?
  196. _horizLine_mem_and    dw      0
  197.             dw    ?
  198. _horizLine_mem_not    dw      0
  199.             dw    ?
  200. _horizLine_mem_or    dw      0
  201.             dw    ?
  202. _horizLine_mem_xor    dw    0
  203.             dw    ?
  204. _vertLine_scr_copy    dw    0             ; vertLine
  205.             dw    ?
  206. _vertLine_scr_and    dw    0
  207.             dw    ?
  208. _vertLine_scr_not    dw    0
  209.             dw    ?
  210. _vertLine_scr_or    dw    0
  211.             dw    ?
  212. _vertLine_scr_xor    dw    0
  213.             dw    ?
  214. _vertLine_mem_copy    dw    0
  215.             dw    ?
  216. _vertLine_mem_and    dw    0
  217.             dw    ?
  218. _vertLine_mem_not    dw    0
  219.             dw    ?
  220. _vertLine_mem_or    dw    0
  221.             dw    ?
  222. _vertLine_mem_xor    dw    0
  223.             dw    ?
  224. _drawRect_scr_copy    dw    0            ; drawRect
  225.             dw    ?
  226. _drawRect_scr_and    dw    0
  227.             dw    ?
  228. _drawRect_scr_not    dw    0
  229.             dw    ?
  230. _drawRect_scr_or    dw    0
  231.             dw    ?
  232. _drawRect_scr_xor    dw    0
  233.             dw    ?
  234. _drawRect_mem_copy    dw    0
  235.             dw    ?
  236. _drawRect_mem_and    dw    0
  237.             dw    ?
  238. _drawRect_mem_not    dw    0
  239.             dw    ?
  240. _drawRect_mem_or    dw    0
  241.             dw    ?
  242. _drawRect_mem_xor    dw    0
  243.             dw    ?
  244. _filledRect_scr_copy    dw    0            ; filledRect
  245.             dw    ?
  246. _filledRect_scr_and    dw      0
  247.             dw    ?
  248. _filledRect_scr_not    dw      0
  249.             dw    ?
  250. _filledRect_scr_or    dw      0
  251.             dw    ?
  252. _filledRect_scr_xor    dw    0
  253.             dw    ?
  254. _filledRect_mem_copy    dw    0
  255.             dw    ?
  256. _filledRect_mem_and    dw    0
  257.             dw    ?
  258. _filledRect_mem_not    dw    0
  259.             dw    ?
  260. _filledRect_mem_or    dw    0
  261.             dw    ?
  262. _filledRect_mem_xor    dw    0
  263.             dw    ?
  264. _clearGraphics_scr_copy    dw    0            ; clearGraphics
  265.             dw    ?
  266. _clearGraphics_scr_and    dw      0
  267.             dw    ?
  268. _clearGraphics_scr_not    dw      0
  269.                   dw    ?
  270. _clearGraphics_scr_or    dw      0
  271.             dw    ?
  272. _clearGraphics_scr_xor    dw    0
  273.             dw    ?
  274. _clearGraphics_mem_copy    dw    0
  275.             dw    ?
  276. _clearGraphics_mem_and    dw    0
  277.             dw    ?
  278. _clearGraphics_mem_not    dw    0
  279.             dw    ?
  280. _clearGraphics_mem_or    dw    0
  281.             dw    ?
  282. _clearGraphics_mem_xor    dw    0
  283.             dw    ?
  284. _ellipse_scr_copy    dw    0            ; ellipse
  285.             dw    ?
  286. _ellipse_scr_and    dw    0
  287.             dw    ?
  288. _ellipse_scr_not    dw    0
  289.             dw    ?
  290. _ellipse_scr_or        dw    0
  291.             dw    ?
  292. _ellipse_scr_xor    dw    0
  293.             dw    ?
  294. _ellipse_mem_copy    dw    0
  295.             dw    ?
  296. _ellipse_mem_and    dw    0
  297.             dw    ?
  298. _ellipse_mem_not    dw    0
  299.             dw    ?
  300. _ellipse_mem_or        dw    0
  301.             dw    ?
  302. _ellipse_mem_xor    dw    0
  303.             dw    ?
  304. _filledEllipse_scr_copy    dw    0            ; filledEllipse
  305.             dw    ?
  306. _filledEllipse_scr_and    dw    0
  307.             dw    ?
  308. _filledEllipse_scr_not    dw    0
  309.             dw    ?
  310. _filledEllipse_scr_or    dw    0
  311.             dw    ?
  312. _filledEllipse_scr_xor    dw    0
  313.             dw    ?
  314. _filledEllipse_mem_copy    dw    0
  315.             dw    ?
  316. _filledEllipse_mem_and    dw    0
  317.             dw    ?
  318. _filledEllipse_mem_not    dw    0
  319.             dw    ?
  320. _filledEllipse_mem_or    dw    0
  321.             dw    ?
  322. _filledEllipse_mem_xor    dw    0
  323.             dw    ?
  324. _circle_scr_copy    dw    0            ; circle
  325.             dw    ?
  326. _circle_scr_and        dw    0
  327.             dw    ?
  328. _circle_scr_not        dw    0
  329.             dw    ?
  330. _circle_scr_or        dw    0
  331.             dw    ?
  332. _circle_scr_xor        dw    0
  333.             dw    ?
  334. _circle_mem_copy    dw    0
  335.             dw    ?
  336. _circle_mem_and        dw    0
  337.             dw    ?
  338. _circle_mem_not        dw    0
  339.             dw    ?
  340. _circle_mem_or        dw    0
  341.             dw    ?
  342. _circle_mem_xor        dw    0
  343.             dw    ?
  344. _filledCircle_scr_copy    dw    0            ; filledCircle
  345.             dw    ?
  346. _filledCircle_scr_and    dw    0
  347.             dw    ?
  348. _filledCircle_scr_not    dw    0
  349.             dw    ?
  350. _filledCircle_scr_or    dw    0
  351.             dw    ?
  352. _filledCircle_scr_xor    dw    0
  353.             dw    ?
  354. _filledCircle_mem_copy    dw    0
  355.             dw    ?
  356. _filledCircle_mem_and    dw    0
  357.             dw    ?
  358. _filledCircle_mem_not    dw    0
  359.             dw    ?
  360. _filledCircle_mem_or    dw    0
  361.             dw    ?
  362. _filledCircle_mem_xor    dw    0
  363.             dw    ?
  364. _fillRegion_scr_copy    dw    0            ; fillRegion
  365.             dw    ?
  366. _fillRegion_scr_and    dw    0
  367.             dw    ?
  368. _fillRegion_scr_not    dw    0
  369.             dw    ?
  370. _fillRegion_scr_or    dw    0
  371.             dw    ?
  372. _fillRegion_scr_xor    dw    0
  373.             dw    ?
  374. _fillRegion_mem_copy    dw    0
  375.             dw    ?
  376. _fillRegion_mem_and    dw    0
  377.             dw    ?
  378. _fillRegion_mem_not    dw    0
  379.             dw    ?
  380. _fillRegion_mem_or    dw    0
  381.             dw    ?
  382. _fillRegion_mem_xor    dw    0
  383.             dw    ?
  384. _fillLine_scr_copy    dw    horizLine_scr_copy    ; fillLine
  385.             dw    ?
  386. _fillLine_scr_and    dw      0
  387.             dw    ?
  388. _fillLine_scr_not    dw      0
  389.             dw    ?
  390. _fillLine_scr_or    dw      0
  391.             dw    ?
  392. _fillLine_scr_xor    dw    0
  393.             dw    ?
  394. _fillLine_mem_copy    dw    horizLine_mem_copy
  395.             dw    ?
  396. _fillLine_mem_and    dw      0
  397.             dw    ?
  398. _fillLine_mem_not    dw      0
  399.             dw    ?
  400. _fillLine_mem_or    dw      0
  401.             dw    ?
  402. _fillLine_mem_xor    dw    0
  403.             dw    ?
  404. ;*** Mode information
  405. scrnMaxX        dw    639    ; physical dimensions
  406. scrnMaxY        dw    479
  407. maxColour        dw    255    ; maximum colour number
  408. xRatio                   dw    4    ; aspect ratio 4:3 (640:480 in
  409. yRatio            dw    3    ;   lowest terms)
  410. bitsPerPixel        dw    8    ; 8 bits per pixel
  411. inMaxX            dw    639    ; current input screen dimensions
  412. inMaxY            dw    479
  413. outMaxX            dw    639    ; current output screen dimensions
  414. outMaxY            dw    479
  415. inScreenWide        dw    ?    ; needed only for virtual screens
  416. outScreenWide        dw    ?
  417. ;*** Viewport information
  418. inViewportULX        dw    0
  419. inViewportULY        dw    0
  420. inViewportLRX        dw    639
  421. inViewportLRY        dw    479
  422. outViewportULX        dw    0
  423. outViewportULY        dw    0
  424. outViewportLRX        dw    639
  425. outViewportLRY        dw    479
  426. ;*** Paging information
  427. pagingSupported        dw    ?    ; not implemented yet
  428. curPage            dw    ?    ; not implemented yet
  429. maxPage            dw    ?    ; not implemented yet
  430. ;*** Force (image width MOD imageWideAdjust) = 0.
  431. imageWideAdjust        dw    ?    ; not implemented yet
  432. ;*** Current and screen addresses
  433.     LABEL    inAddr    DWORD        ; current input address
  434. inOff    dw    0
  435. inSeg    dw    0A000h
  436.     LABEL    outAddr    DWORD        ; current output address
  437. outOff    dw    0
  438. outSeg    dw    0A000h
  439.     LABEL    scrAddr    DWORD        ; screen address
  440. scrOff    dw    0
  441. scrSeg    dw    0A000h
  442. ;*** Copyright string
  443.     db    'The Graphics Engine -- Copyright (c) 1993 by Matthew Hildebrand'
  444.  
  445.  
  446. inited        db    0
  447. colourPalette    db    768    DUP(?)
  448. lineOffs    dw    SCREEN_DEEP    DUP(?)
  449. bankNum        dw    SCREEN_DEEP    DUP(?)
  450. bankChanges    dw    SCREEN_DEEP    DUP(?)
  451. curBank        dw    ?
  452. screenWide    dw    ?
  453.  
  454. bankadr        dw    OFFSET _nobank
  455. vgamem        dw    ?
  456. bksize        dw    ?
  457. bksizeShl10Dec    dw    ?
  458. retval        dw    ?        ; first return value from whichVGA()
  459. scanline    dw    ?
  460.  
  461. acumos        dw    ?
  462. aheada        dw    ?
  463. aheadb        dw    ?
  464. ativga        dw    ?
  465. chipstech     dw    ?
  466. cirrus        dw    ?
  467. compaq        dw    ?
  468. everex        dw    ?
  469. genoa        dw    ?
  470. ncr        dw    ?
  471. oak067        dw    ?
  472. paradise     dw    ?
  473. trident        dw    ?
  474. t8900        dw    ?
  475. tseng        dw    ?
  476. tseng4        dw    ?
  477. video7        dw    ?
  478. vesa        dw    ?
  479.  
  480.  
  481. ; VESA information
  482.     STRUC    vgainfo
  483. VESASignature    db    4 dup (?)    ; 4 signature bytes
  484. VESAVersion    dw    ?        ; VESA version number
  485. OEMStringPtr    dd    ?        ; Pointer to OEM string
  486. Capabilities    db    4 dup (?)    ; Capabilities of the video environment
  487. VideoModePtr    dd    ?        ; Pointer to supported Super VGA modes
  488.     ENDS
  489.     STRUC    vesamode
  490. ModeAttributes    dw    ?    ; mode attributes
  491. WinAAttributes    db    ?    ; window A attributes
  492. WinBAttributes    db    ?    ; window B attributes
  493. WinGranularity    dw    ?    ; window granularity
  494. WinSize        dw    ?    ; window size
  495. WinASegment    dw    ?    ; window A start segment
  496. WinBSegment    dw    ?    ; window B start segment
  497. WinFuncPtr    dd    ?    ; pointer to window function
  498. BytesPerLine    dw    ?    ; bytes per scan line
  499. ; optional information (provided if bit D1 of ModeAttributes is set)
  500. XResolution    dw    ?    ; horizontal resolution
  501. YResolution    dw    ?    ; vertical resolution
  502. XCharSize    db    ?    ; character cell width
  503. YCharSize    db    ?    ; character cell height
  504. NumberOfPlanes    db    ?    ; number of memory planes
  505. BitsPerPixel    db    ?    ; bits per pixel
  506. NumberOfBanks    db    ?    ; number of banks
  507. MemoryModel    db    ?    ; memory model type
  508. BankSize    db    ?    ; bank size in kb
  509.     db    227    DUP(?)    ; pad to 256 bytes
  510.     ENDS
  511.  
  512. vesabuf        db    256    DUP(?)
  513. modebuf        vesamode    ?
  514.  
  515.  
  516. MACRO    NEWBANK
  517.   call    [bankadr]
  518. ENDM
  519.  
  520.  
  521. ;*****
  522. ;***** initGraphics
  523. ;*****
  524.  
  525. PROC    C    initGraphics
  526.   cmp    [inited],0
  527.   je    @@NotInited
  528.   call    setMode
  529.   mov    ax,1
  530.   retf
  531.  
  532.       @@NotInited:
  533.   call    whichVGA
  534.   or    ax,ax                ; was function successful?
  535.   jz    @@Error                ; no, quit
  536.   call    setMode
  537.   or    ax,ax                 ; was function successful?
  538.   jz    @@Error                ; no, quit
  539.   call    makeAddrTable
  540.  
  541.   cmp    [vgamem],512            ; ensure enough memory
  542.   jb    @@Error                ; abort if <512 K of video RAM
  543.  
  544.   mov    ax,[bksize]            ; initialize bksizeShl10Dec
  545.   shl    ax,10                ; shift it
  546.   dec    ax                ; decrement it
  547.   mov    [bksizeShl10Dec],ax        ; store it
  548.  
  549.   mov    ax,1
  550.   mov    [inited],al
  551.   retf
  552.  
  553.     @@Error:
  554.   xor    ax,ax
  555.   retf
  556. ENDP
  557.  
  558.  
  559. ;*****
  560. ;***** putLine
  561. ;*****
  562.  
  563. PROC    C    putLine_scr_copy
  564.     ARG    lineNum:WORD, xOff:WORD, lineLen:WORD, buf:DATAPTR
  565.   push    ds si di
  566.  
  567.   cld
  568.   mov    bx,[lineNum]            ; Decide if bank changes mid-line
  569.   shl    bx,1
  570.   cmp    [cs:bankChanges+bx],0
  571.   jne    @@BankChanged
  572.  
  573.   mov    ax,[cs:bankNum+bx]
  574.   cmp    ax,[curBank]            ; set bank only if necessary
  575.   je    @@NoNewBank
  576.   NEWBANK
  577.  
  578.       @@NoNewBank:
  579.   mov    cx,[lineLen]            ; blast the line into video memory
  580.   mov    ax,0A000h
  581.   mov    es,ax
  582.   mov    di,[cs:lineOffs+bx]
  583.   add    di,[xOff]
  584.   lds    si,[buf]
  585.   shr    cx,1
  586.   rep    movsw
  587.   jnc    @@Exit
  588.   movsb
  589.       @@Exit:
  590.   pop    di si ds
  591.   leave
  592.   retf
  593.  
  594.       @@BankChanged:                  ; slow pixel-by-pixel
  595.   mov    cx,[lineLen]
  596.   mov    dx,[lineNum]
  597.   mov    bx,[xOff]
  598.   lds    si,[buf]
  599.     @@Loop:
  600.   lodsb
  601.   push    bx cx dx si
  602.   call    far putPixel_scr_copy C,bx,dx,ax
  603.   pop    si dx cx bx
  604.   inc    bx
  605.   loop    @@Loop
  606.  
  607.   pop    di si ds
  608.   leave
  609.   retf
  610. ENDP
  611.  
  612. PROC    C    putLine_mem_copy
  613.     ARG    y:WORD, xOff:WORD, lineLen:WORD, buf:DATAPTR
  614.   push    ds si di            ; save these registers
  615.  
  616.   xor    eax,eax                ; clear EAX
  617.   xor    edx,edx                ; clear EDX
  618.   xor    edi,edi                ; clear EDI
  619.  
  620.   les    di,[outAddr]            ; load output address
  621.   mov    ax,[y]
  622.   mov    dx,[outScreenWide]
  623.   mul    edx                    ; EDX:EAX = offset - EDI - x
  624.   add    edi,eax                ; EDI = offset - x
  625.   mov    dx,[xOff]
  626.   add    edi,edx                ; EDI = offset
  627.   mov    edx,edi                ; EDX = offset
  628.   shr    edx,4                ; EDX = # of paragraphs (segments)
  629.   add    dx,[outSeg]            ; DX = new segment
  630.   mov    es,dx                ; ES = new segment
  631.   and    di,0000000000001111b             ; DI = offset within new segment
  632.  
  633.   lds    si,[buf]            ; load input address
  634.   mov    dx,si                ; DX = offset
  635.   shr    dx,4                ; DX = # of paragraphs (segments)
  636.   mov    ax,ds                ; AX = DS
  637.   add    ax,dx                ; AX = new DS
  638.   mov    ds,ax                ; DS = new DS
  639.   and    si,0000000000001111b        ; SI = offset within new segment
  640.  
  641.   cld
  642.   mov    cx,[lineLen]            ; CX = line length
  643.   mov    dx,cx                ; DX = line length
  644.   shr    cx,2                ; CX = line length in dwords
  645.   rep    movsd                     ; move the dwords if necessary
  646.   mov    cx,dx                ; CX = line length in bytes
  647.   and    cx,0000000000000011b        ; CX = any residual bytes
  648.   rep    movsb                ; move the bytes if necessary
  649.  
  650.   pop    di si ds            ; restore registers
  651.   leave                    ; clean up
  652.   retf                    ; return
  653. ENDP
  654.  
  655.  
  656. ;*****
  657. ;***** getLine
  658. ;*****
  659.  
  660. PROC    C    getLine_scr
  661.     ARG    lineNum:WORD, xOff:WORD, lineLen:WORD, buf:DATAPTR
  662.   push    ds si di
  663.  
  664.   cld
  665.   mov    bx,[lineNum]            ; Decide if bank changes mid-line
  666.   shl    bx,1
  667.   cmp    [cs:bankChanges+bx],0
  668.   jne    @@BankChanged
  669.  
  670.   mov    ax,[cs:bankNum+bx]
  671.   cmp    ax,[curBank]            ; set bank only if necessary
  672.   je    @@NoNewBank
  673.   NEWBANK
  674.  
  675.     @@NoNewBank:
  676.   mov    cx,[lineLen]            ; blast the line into video memory
  677.   mov    ax,0A000h
  678.   mov    ds,ax
  679.   mov    si,[cs:lineOffs+bx]
  680.   add    si,[xOff]
  681.   les    di,[buf]
  682.   shr    cx,1
  683.   rep    movsw
  684.   jnc    @@Exit
  685.   movsb
  686.     @@Exit:
  687.   pop    di si ds
  688.   leave
  689.   retf
  690.  
  691.     @@BankChanged:                  ; slow pixel-by-pixel
  692.   mov    cx,[lineLen]
  693.   mov    dx,[lineNum]
  694.   mov    bx,[xOff]
  695.   les    di,[buf]
  696.     @@Loop:
  697.   push    bx cx dx di es
  698.   call    far getPixel_scr C,bx,dx
  699.   pop    es di dx cx bx
  700.   stosb
  701.   inc    bx
  702.   loop    @@Loop
  703.  
  704.   pop    di si ds
  705.   leave
  706.   retf
  707. ENDP
  708.  
  709. PROC    C    getLine_mem
  710.     ARG    y:WORD, xOff:WORD, lineLen:WORD, buf:DATAPTR
  711.   push    ds si di            ; save these registers
  712.  
  713.   xor    eax,eax                ; clear EAX
  714.   xor    edx,edx                ; clear EDX
  715.   xor    esi,esi                ; clear ESI
  716.  
  717.   les    si,[inAddr]            ; load input address
  718.   mov    ax,[y]
  719.   mov    dx,[inScreenWide]
  720.   mul    edx                    ; EDX:EAX = offset - ESI - x
  721.   add    esi,eax                ; ESI = offset - x
  722.   mov    dx,[xOff]
  723.   add    esi,edx                ; ESI = offset
  724.   mov    edx,esi                ; EDX = offset
  725.   shr    edx,4                ; EDX = # of paragraphs (segments)
  726.   add    dx,[inSeg]            ; DX = new segment
  727.   mov    ds,dx                ; ES = new segment
  728.   and    si,0000000000001111b             ; SI = offset within new segment
  729.  
  730.   les    di,[buf]            ; load output address
  731.   mov    dx,di                ; DX = offset
  732.   shr    dx,4                ; DX = # of paragraphs (segments)
  733.   mov    ax,es                ; AX = ES
  734.   add    ax,dx                ; AX = new ES
  735.   mov    es,ax                ; ES = new ES
  736.   and    di,0000000000001111b        ; DI = offset within new segment
  737.  
  738.   cld
  739.   mov    cx,[lineLen]            ; CX = line length
  740.   mov    dx,cx                ; DX = line length
  741.   shr    cx,2                ; CX = line length in dwords
  742.   rep    movsd                     ; move the dwords if necessary
  743.   mov    cx,dx                ; CX = line length in bytes
  744.   and    cx,0000000000000011b        ; CX = any residual bytes
  745.   rep    movsb                ; move the bytes if necessary
  746.  
  747.   pop    di si ds            ; restore registers
  748.   leave                    ; clean up
  749.   retf                    ; return
  750. ENDP
  751.  
  752.  
  753. ;*****
  754. ;***** putPixel
  755. ;*****
  756.  
  757. ; Copy a pixel to the screen
  758. PROC    C    putPixel_scr_copy
  759.     ARG    x:WORD, y:WORD, colour:BYTE
  760.   mov    bx,[y]                ; BX = y coordinate
  761.   shl    bx,1                ; to access a table of words
  762.   mov    ax,[cs:bankNum+bx]        ; AX = bank at start of line
  763.   mov    bx,[cs:lineOffs+bx]        ; DX = offset at start of line
  764.   add    bx,[x]                ; BX = offset of pixel
  765.   adc    ax,0                ; in case of overflow, inc AX
  766.   mov    dx,[bksizeShl10Dec]        ; DX = bank size in bytes - 1
  767.   cmp    bx,dx                ; is offset > than bank size
  768.   jbe    @@offsetOK            ; no, proceed
  769.  
  770.   sub    bx,dx                ; BX = fixed offset
  771.   inc    ax                ; AX = new bank
  772.  
  773.     @@offsetOK:
  774.   cmp    ax,[curBank]
  775.   je    @@NoNew
  776.   NEWBANK                ; switch banks if a new bank entered
  777.     @@NoNew:
  778.   mov    ax,0A000h            ; setup screen segment A000
  779.   mov    es,ax
  780.   mov    al,[colour]            ; get color of pixel to plot
  781.   mov    [es:bx],al
  782.   leave
  783.   retf
  784. ENDP
  785.  
  786. ; Copy a pixel to memory
  787. PROC    C    putPixel_mem_copy
  788.     ARG    x:WORD,y:WORD,colour:BYTE
  789.   xor    eax,eax                ; clear EAX
  790.   xor    ebx,ebx                ; clear EBX
  791.   xor    edx,edx                ; clear EDX
  792.  
  793.   les    bx,[outAddr]            ; load output address
  794.   mov    ax,[y]
  795.   mov    dx,[outScreenWide]
  796.   mul    edx                    ; EDX:EAX = offset - EBX - x
  797.   add    ebx,eax                ; EBX = offset - x
  798.   mov    dx,[x]
  799.   add    ebx,edx                ; EBX = offset
  800.  
  801.   mov    edx,ebx                ; EDX = offset
  802.   shr    edx,4                ; EDX = # of paragraphs (segments)
  803.   add    dx,[outSeg]            ; DX = new segment
  804.   mov    es,dx                ; ES = new segment
  805.   and    bx,0000000000001111b             ; BX = offset within new segment
  806.  
  807.   mov    al,[colour]            ; colour in AL
  808.   mov    [es:bx],al            ; store pixel
  809.   leave                    ; clean up
  810.   retf                    ; return
  811. ENDP
  812.  
  813. ; AND a pixel to memory
  814. PROC    C    putPixel_mem_and
  815.     ARG    x:WORD,y:WORD,colour:BYTE
  816.   xor    eax,eax                ; clear EAX
  817.   xor    ebx,ebx                ; clear EBX
  818.   xor    edx,edx                ; clear EDX
  819.  
  820.   les    bx,[outAddr]            ; load output address
  821.   mov    ax,[y]
  822.   mov    dx,[outScreenWide]
  823.   mul    edx                    ; EDX:EAX = offset - EBX - x
  824.   add    ebx,eax                ; EBX = offset - x
  825.   mov    dx,[x]
  826.   add    ebx,edx                ; EBX = offset
  827.  
  828.   mov    edx,ebx                ; EDX = offset
  829.   shr    edx,4                ; EDX = # of paragraphs (segments)
  830.   add    dx,[outSeg]            ; DX = new segment
  831.   mov    es,dx                ; ES = new segment
  832.   and    bx,0000000000001111b             ; BX = offset within new segment
  833.  
  834.   mov    al,[colour]            ; colour in AL
  835.   and    [es:bx],al            ; AND pixel
  836.   leave                    ; clean up
  837.   retf                    ; return
  838. ENDP
  839.  
  840. ; NOT a pixel to memory
  841. PROC    C    putPixel_mem_not
  842.     ARG    x:WORD,y:WORD,colour:BYTE
  843.   xor    eax,eax                ; clear EAX
  844.   xor    ebx,ebx                ; clear EBX
  845.   xor    edx,edx                ; clear EDX
  846.  
  847.   les    bx,[outAddr]            ; load output address
  848.   mov    ax,[y]
  849.   mov    dx,[outScreenWide]
  850.   mul    edx                    ; EDX:EAX = offset - EBX - x
  851.   add    ebx,eax                ; EBX = offset - x
  852.   mov    dx,[x]
  853.   add    ebx,edx                ; EBX = offset
  854.  
  855.   mov    edx,ebx                ; EDX = offset
  856.   shr    edx,4                ; EDX = # of paragraphs (segments)
  857.   add    dx,[outSeg]            ; DX = new segment
  858.   mov    es,dx                ; ES = new segment
  859.   and    bx,0000000000001111b             ; BX = offset within new segment
  860.  
  861.   mov    al,[colour]            ; colour in AL
  862.   not    al                ; NOT it
  863.   mov    [es:bx],al            ; store NOTed pixel
  864.   leave                    ; clean up
  865.   retf                    ; return
  866. ENDP
  867.  
  868. ; OR a pixel to memory
  869. PROC    C    putPixel_mem_or
  870.     ARG    x:WORD,y:WORD,colour:BYTE
  871.   xor    eax,eax                ; clear EAX
  872.   xor    ebx,ebx                ; clear EBX
  873.   xor    edx,edx                ; clear EDX
  874.  
  875.   les    bx,[outAddr]            ; load output address
  876.   mov    ax,[y]
  877.   mov    dx,[outScreenWide]
  878.   mul    edx                    ; EDX:EAX = offset - EBX - x
  879.   add    ebx,eax                ; EBX = offset - x
  880.   mov    dx,[x]
  881.   add    ebx,edx                ; EBX = offset
  882.  
  883.   mov    edx,ebx                ; EDX = offset
  884.   shr    edx,4                ; EDX = # of paragraphs (segments)
  885.   add    dx,[outSeg]            ; DX = new segment
  886.   mov    es,dx                ; ES = new segment
  887.   and    bx,0000000000001111b             ; BX = offset within new segment
  888.  
  889.   mov    al,[colour]            ; colour in AL
  890.   or    [es:bx],al            ; OR pixel
  891.   leave                    ; clean up
  892.   retf                    ; return
  893. ENDP
  894.  
  895. ; XOR a pixel to memory
  896. PROC    C    putPixel_mem_xor
  897.     ARG    x:WORD,y:WORD,colour:BYTE
  898.   xor    eax,eax                ; clear EAX
  899.   xor    ebx,ebx                ; clear EBX
  900.   xor    edx,edx                ; clear EDX
  901.  
  902.   les    bx,[outAddr]            ; load output address
  903.   mov    ax,[y]
  904.   mov    dx,[outScreenWide]
  905.   mul    edx                    ; EDX:EAX = offset - EBX - x
  906.   add    ebx,eax                ; EBX = offset - x
  907.   mov    dx,[x]
  908.   add    ebx,edx                ; EBX = offset
  909.  
  910.   mov    edx,ebx                ; EDX = offset
  911.   shr    edx,4                ; EDX = # of paragraphs (segments)
  912.   add    dx,[outSeg]            ; DX = new segment
  913.   mov    es,dx                ; ES = new segment
  914.   and    bx,0000000000001111b             ; BX = offset within new segment
  915.  
  916.   mov    al,[colour]            ; colour in AL
  917.   xor    [es:bx],al            ; XOR pixel
  918.   leave                    ; clean up
  919.   retf                    ; return
  920. ENDP
  921.  
  922.  
  923. ;*****
  924. ;***** getPixel
  925. ;*****
  926.  
  927. ; Get a pixel from the screen
  928. PROC    C    getPixel_scr
  929.     ARG    x:WORD, y:WORD
  930.   mov    bx,[y]                ; BX = y coordinate
  931.   shl    bx,1                ; to access a table of words
  932.   mov    ax,[cs:bankNum+bx]        ; AX = bank at start of line
  933.   mov    bx,[cs:lineOffs+bx]        ; DX = offset at start of line
  934.   add    bx,[x]                ; BX = offset of pixel
  935.   adc    ax,0                ; in case of overflow, inc AX
  936.   mov    dx,[bksizeShl10Dec]        ; DX = bank size in bytes - 1
  937.   cmp    bx,dx                ; is offset > than bank size
  938.   jb    @@offsetOK            ; no, proceed
  939.  
  940.   sub    bx,dx                ; BX = fixed offset
  941.   inc    ax                ; AX = new bank
  942.  
  943.     @@offsetOK:
  944.   cmp    ax,[curBank]
  945.   je    @@NoNew
  946.   NEWBANK                ; switch banks if a new bank entered
  947.     @@NoNew:
  948.   mov    ax,0A000h            ; setup screen segment A000
  949.   mov    es,ax
  950.   mov    al,[es:bx]            ; AL = colour for return
  951.   leave
  952.   retf
  953. ENDP
  954.  
  955. ; Get a pixel from memory
  956. PROC    C    getPixel_mem
  957.     ARG    x:WORD,y:WORD
  958.   xor    eax,eax                ; clear EAX
  959.   xor    ebx,ebx                ; clear EBX
  960.   xor    edx,edx                ; clear EDX
  961.  
  962.   les    bx,[inAddr]            ; load input address
  963.   mov    ax,[y]
  964.   mov    dx,[inScreenWide]
  965.   mul    edx                    ; EDX:EAX = offset - EBX - x
  966.   add    ebx,eax                ; EBX = offset - x
  967.   mov    dx,[x]
  968.   add    ebx,edx                ; EBX = offset
  969.  
  970.   mov    edx,ebx                ; EDX = offset
  971.   shr    edx,4                ; EDX = # of paragraphs (segments)
  972.   add    dx,[inSeg]            ; DX = new segment
  973.   mov    es,dx                ; ES = new segment
  974.   and    bx,0000000000001111b             ; BX = offset within new segment
  975.  
  976.   xor    ax,ax                ; clear AX
  977.   mov    al,[es:bx]            ; store pixel in AX for return
  978.   leave                    ; clean up
  979.   retf                    ; return
  980. ENDP
  981.  
  982.  
  983. ;*****
  984. ;***** horizLine
  985. ;*****
  986.  
  987. PROC    C    horizLine_scr_copy
  988.     ARG    y:WORD, x1:WORD, x2:WORD, colour:BYTE
  989.   push    di
  990.  
  991.   cld
  992.   mov    bx,[y]                ; Decide if bank changes mid-line
  993.   shl    bx,1
  994.   cmp    [cs:bankChanges+bx],0
  995.   jne    @@BankChanged
  996.  
  997.   mov    ax,[cs:bankNum+bx]
  998.   cmp    ax,[curBank]            ; set bank only if necessary
  999.   je    @@NoNewBank
  1000.   NEWBANK
  1001.  
  1002.     @@NoNewBank:
  1003.   mov    ax,0A000h
  1004.   mov    es,ax
  1005.   mov    ax,[x1]
  1006.   mov    di,[cs:lineOffs+bx]
  1007.   add    di,ax
  1008.   mov    cx,[x2]                ; blast the line into video memory
  1009.   inc    cx
  1010.   sub    cx,ax
  1011.   mov    al,[colour]
  1012.   mov    ah,al
  1013.   shr    cx,1
  1014.   rep    stosw
  1015.   jnc    @@Exit
  1016.   stosb
  1017.  
  1018.     @@Exit:
  1019.   pop    di
  1020.   leave
  1021.   retf
  1022.  
  1023.     @@BankChanged:                  ; slow pixel-by-pixel
  1024.   mov    bx,[x1]
  1025.   mov    cx,[x2]
  1026.   inc    cx
  1027.   sub    cx,bx
  1028.   mov    dx,[y]
  1029.     @@Loop:
  1030.   push    bx cx dx
  1031.   mov    al,[colour]
  1032.   call    far putPixel_scr_copy C,bx,dx,ax
  1033.   pop    dx cx bx
  1034.   inc    bx
  1035.   loop    @@Loop
  1036.  
  1037.   pop    di
  1038.   leave
  1039.   retf
  1040. ENDP
  1041.  
  1042. PROC    C    horizLine_mem_copy
  1043.     ARG    y:WORD, x1:WORD, x2:WORD, colour:BYTE
  1044.   push    edi                ; store EDI
  1045.  
  1046.   xor    eax,eax                ; clear EAX
  1047.   xor    edi,edi                ; clear EDI
  1048.   xor    edx,edx                ; clear EDX
  1049.  
  1050.   les    di,[outAddr]            ; load output address
  1051.   mov    ax,[y]
  1052.   mov    dx,[outScreenWide]
  1053.   mul    edx                    ; EDX:EAX = offset - EDI - x
  1054.   add    edi,eax                ; EDI = offset - x
  1055.   mov    dx,[x1]
  1056.   add    edi,edx                ; EDI = offset
  1057.   mov    edx,edi                ; EDX = offset
  1058.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1059.   add    dx,[outSeg]            ; DX = new segment
  1060.   mov    es,dx                ; ES = new segment
  1061.   and    di,0000000000001111b             ; DI = offset within new segment
  1062.  
  1063.   mov    al,[colour]            ; colour in AL
  1064.   mov    ah,al                ; colour in AH
  1065.   mov    bx,ax
  1066.   shl    eax,16
  1067.   mov    ax,bx                 ; colour in each byte of EAX
  1068.  
  1069.   mov    cx,[x2]
  1070.   sub    cx,[x1]
  1071.   inc    cx                ; CX = line length in pixels
  1072.   mov    dx,cx                ; DX = line length in bytes
  1073.  
  1074.   shr    cx,2                ; CX = line length in dwords
  1075.   rep    stosd                ; store four bytes at a time
  1076.   mov    cx,dx                ; CX = line length in pixels
  1077.   and    cx,0000000000000011b        ; CX = any remaining bytes
  1078.   rep    stosb                ; store the remaining bytes
  1079.  
  1080.   pop    edi                    ; restore EDI
  1081.   leave                    ; clean up
  1082.   retf                    ; return
  1083. ENDP
  1084.  
  1085.  
  1086. ;*****
  1087. ;***** setPaletteReg
  1088. ;*****
  1089.  
  1090. PROC    C    setPaletteReg
  1091.     ARG    palNum:WORD,red:BYTE,green:BYTE,blue:BYTE
  1092.   mov    bx,[palNum]
  1093.  
  1094.   mov    dx,3C8h                ; set for correct palette register
  1095.   mov    ax,[palNum]
  1096.   out    dx,al
  1097.   inc    dx
  1098.  
  1099.   mov    al,[red]            ; red
  1100.   shr    al,2
  1101.   jnc    @@L1
  1102.   cmp    al,63
  1103.   je    @@L1
  1104.   inc    al
  1105.     @@L1:
  1106.   out    dx,al
  1107.  
  1108.   mov    al,[green]            ; green
  1109.   shr    al,2
  1110.   jnc    @@L2
  1111.   cmp    al,63
  1112.   je    @@L2
  1113.   inc    al
  1114.     @@L2:
  1115.   out    dx,al
  1116.  
  1117.   mov    al,[blue]            ; blue
  1118.   shr    al,2
  1119.   jnc    @@L3
  1120.   cmp    al,63
  1121.   je    @@L3
  1122.   inc    al
  1123.     @@L3:
  1124.   out    dx,al
  1125.  
  1126.   leave
  1127.   retf
  1128. ENDP
  1129.  
  1130.  
  1131. ;*****
  1132. ;***** getPaletteReg
  1133. ;*****
  1134.  
  1135. PROC    C    getPaletteReg
  1136.     ARG    palNum:WORD,red:DATAPTR,green:DATAPTR,blue:DATAPTR
  1137.   push    ds si
  1138.  
  1139.   mov    dx,3C7h                ; set for correct palette register
  1140.   mov    ax,[palNum]
  1141.   out    dx,al
  1142.   mov    dx,3C9h
  1143.  
  1144.   in    al,dx                ; red
  1145.   lds    si,[red]
  1146.   shl    al,2
  1147.   mov    [ds:si],al
  1148.   in    al,dx                ; green
  1149.   lds    si,[green]
  1150.   shl    al,2
  1151.   mov    [ds:si],al
  1152.   in    al,dx                ; blue
  1153.   lds    si,[blue]
  1154.   shl    al,2
  1155.   mov    [ds:si],al
  1156.  
  1157.   pop    si ds
  1158.   leave
  1159.   retf
  1160. ENDP
  1161.  
  1162.  
  1163. ;*****
  1164. ;***** setBlockPalette
  1165. ;*****
  1166.  
  1167. PROC    C    setBlockPalette
  1168.     ARG    firstReg:WORD,lastReg:WORD,paletteData:DATAPTR
  1169.   push    ds si
  1170.  
  1171.   lds    si,[paletteData]        ; set up
  1172.   mov    dx,3C8h
  1173.   mov    ax,[firstReg]
  1174.   out    dx,al
  1175.   inc    dx
  1176.   mov    cx,[lastReg]            ; CX = number of registers
  1177.   sub    cx,ax
  1178.   inc    cx
  1179.   cld
  1180.  
  1181.     @@LLoop:
  1182.   lodsb            ; red
  1183.   shr    al,2
  1184.   jnc    @@L1
  1185.   cmp    al,63
  1186.   je    @@L1
  1187.   inc    al
  1188.       @@L1:
  1189.   out    dx,al
  1190.  
  1191.   lodsb            ; green
  1192.   shr    al,2
  1193.   jnc    @@L2
  1194.   cmp    al,63
  1195.   je    @@L2
  1196.   inc    al
  1197.       @@L2:
  1198.   out    dx,al
  1199.  
  1200.   lodsb            ; blue
  1201.   shr    al,2
  1202.   jnc    @@L3
  1203.   cmp    al,63
  1204.   je    @@L3
  1205.   inc    al
  1206.       @@L3:
  1207.   out    dx,al
  1208.  
  1209.   loop    @@LLoop
  1210.  
  1211.     @@LExit:
  1212.   pop    si ds
  1213.   leave
  1214.   retf
  1215. ENDP
  1216.  
  1217.  
  1218. ;*****
  1219. ;***** getBlockPalette
  1220. ;*****
  1221.  
  1222. PROC    C    getBlockPalette
  1223.     ARG    firstReg:WORD,lastReg:WORD,paletteData:DATAPTR
  1224.   push    di
  1225.  
  1226.   les    di,[paletteData]        ; set up
  1227.   mov    dx,3C7h
  1228.   mov    ax,[firstReg]
  1229.   out    dx,al
  1230.   mov    dx,3C9h
  1231.   mov    cx,[lastReg]            ; CX = number of registers
  1232.   sub    cx,ax
  1233.   inc    cx
  1234.   cld
  1235.  
  1236.     @@L1:
  1237.   in    al,dx
  1238.   shl    al,2
  1239.   stosb            ; red
  1240.   in    al,dx
  1241.   shl    al,2
  1242.   stosb            ; green
  1243.   in    al,dx
  1244.   shl    al,2
  1245.   stosb            ; blue
  1246.   loop    @@L1
  1247.  
  1248.     @@LExit:
  1249.   pop    di
  1250.   leave
  1251.   retf
  1252. ENDP
  1253.  
  1254.  
  1255. ;*****
  1256. ;***** Bank switching routines
  1257. ;*****
  1258.  
  1259. _acumos:                ; AcuMos
  1260.   push    ax dx ax
  1261.   cli
  1262.   mov    [curBank],ax
  1263.   mov    dx,3C4h            ; sequencer index 6
  1264.   mov    ax,1206h        ; disable write protect on VGA registers
  1265.   out    dx,ax
  1266.   mov    dx,3CEh
  1267.   pop    ax
  1268.   mov    ah,al
  1269.   mov    al,9
  1270.   out    dx,ax
  1271.   sti
  1272.   pop    dx ax
  1273.   ret
  1274.  
  1275. _aheada:                ; Ahead Systems Ver A
  1276.   push    ax dx cx
  1277.   cli
  1278.   mov    [curBank],ax
  1279.   mov    ch,al
  1280.   mov    dx,3CEh            ; Enable extended registers
  1281.   mov    ax,200Fh
  1282.   out    dx,ax
  1283.   mov    dl,0CCh            ; bit 0
  1284.   in    al,dx
  1285.   mov    dl,0C2h
  1286.   and    al,11011111b
  1287.   shr    ch,1
  1288.   jnc    @@skpa
  1289.   or    al,00100000b
  1290.       @@skpa:
  1291.   out    dx,al
  1292.   mov    dl,0CFh            ; bits 1,2,3
  1293.   xor    al,al
  1294.   out    dx,al
  1295.   inc    dx
  1296.   in    al,dx
  1297.   dec    dx
  1298.   and    al,11111000b
  1299.   or    al,ch
  1300.   mov    ah,al
  1301.   xor    al,al
  1302.   out    dx,ax
  1303.   sti
  1304.   pop    cx dx ax
  1305.   ret
  1306.  
  1307. _aheadb:                ; Ahead Systems Ver B
  1308.   push    ax dx cx
  1309.   cli
  1310.   mov    [curBank],ax
  1311.   mov    ch,al
  1312.   mov    dx,3CEh            ; Enable extended registers
  1313.   mov    ax,200Fh
  1314.   out    dx,ax
  1315.   mov    ah,ch
  1316.   mov    cl,4
  1317.   shl    ah,cl
  1318.   or    ah,ch
  1319.   mov    al,0Dh
  1320.   out    dx,ax
  1321.   sti
  1322.   pop    cx dx ax
  1323.   ret
  1324.  
  1325. _ativga:                ; ATI VGA Wonder
  1326.   push    ax dx
  1327.   cli
  1328.   mov    [curBank],ax
  1329.   mov    ah,al
  1330.   mov    dx,1CEh
  1331.   mov    al,0B2h
  1332.   out    dx,al
  1333.   inc    dl
  1334.   in    al,dx
  1335.   shl    ah,1
  1336.   and    al,0E1h
  1337.   or    ah,al
  1338.   mov    al,0B2h
  1339.   dec    dl
  1340.   out    dx,ax
  1341.   sti
  1342.   pop    dx ax
  1343.   ret
  1344.  
  1345. _chipstech:                ; Chips & Tech
  1346.   push    ax dx ax
  1347.   cli
  1348.   mov    [curBank],ax
  1349.   mov    dx,46E8h        ; place chip in setup mode
  1350.   mov    ax,1Eh
  1351.   out    dx,ax
  1352.   mov    dx,103h            ; enable extended registers
  1353.   mov    ax,0080h
  1354.   out    dx,ax
  1355.   mov    dx,46E8h        ; bring chip out of setup mode
  1356.   mov    ax,0Eh
  1357.   out    dx,ax
  1358.   pop    ax
  1359.   mov    ah,al
  1360.   mov    al,10h
  1361.   mov    dx,3D6h
  1362.   out    dx,ax
  1363.   sti
  1364.   pop    dx ax
  1365.   ret
  1366.  
  1367. _cirrus:                ; Cirrus
  1368.   push    ax dx
  1369.   cli
  1370.   mov    [curBank],ax
  1371.   mov    dx,3CEh
  1372.   mov    ah,al
  1373.   mov    al,9
  1374.   out    dx,ax
  1375.   sti
  1376.   pop    dx ax
  1377.   ret
  1378.  
  1379. _compaq:                ; Compaq
  1380.   push    ax dx ax
  1381.   cli
  1382.   mov    [curBank],ax
  1383.   mov    dx,3CEh
  1384.   mov    ax,50Fh            ; unlock extended registers
  1385.   out    dx,ax
  1386.   pop    ax
  1387.   mov    ah,al
  1388.   mov    al,45h
  1389.   out    dx,ax
  1390.   sti
  1391.   pop    dx ax
  1392.   ret
  1393.  
  1394. _everex:                ; Everex
  1395.   push    ax dx cx
  1396.   cli
  1397.   mov    [curBank],ax
  1398.   mov    cl,al
  1399.   mov    dx,3C4h
  1400.   mov    al,8
  1401.   out    dx,al
  1402.   inc    dl
  1403.   in    al,dx
  1404.   dec    dl
  1405.   shl    al,1
  1406.   shr    cl,1
  1407.   rcr    al,1
  1408.   mov    ah,al
  1409.   mov    al,8
  1410.   out    dx,ax
  1411.   mov    dl,0CCh
  1412.   in    al,dx
  1413.   mov    dl,0C2h
  1414.   and    al,0DFh
  1415.   shr    cl,1
  1416.   jc    @@nob2
  1417.   or    al,20h
  1418.       @@nob2:
  1419.   out    dx,al
  1420.   sti
  1421.   pop    cx dx ax
  1422.   ret
  1423.  
  1424. _genoa:                    ; GENOA GVGA
  1425.   push    ax dx
  1426.   cli
  1427.   mov    [curBank],ax
  1428.   mov    ah,al
  1429.   shl    al,3
  1430.   or    ah,al
  1431.   mov    al,6
  1432.   or    ah,40h
  1433.   mov    dx,3C4h
  1434.   out    dx,ax
  1435.   sti
  1436.   pop    dx ax
  1437.   ret
  1438.  
  1439. _ncr:                    ; NCR 77C22E
  1440.   push    ax dx
  1441.   cli
  1442.   mov    [curBank],ax
  1443.   mov    ah,al
  1444.   mov    al,18h
  1445.   mov    dx,3C4h
  1446.   out    dx,ax
  1447.   mov    ax,19h
  1448.   out    dx,ax
  1449.   sti
  1450.   pop    dx ax
  1451.   ret
  1452.  
  1453. _oak067:                                ; Oak Technology OTI-067
  1454.   push    ax dx
  1455.   cli
  1456.   mov    [curBank],ax
  1457.   and    al,15
  1458.   mov    ah,al
  1459.   shl    al,4
  1460.   or    ah,al
  1461.   mov    al,11h
  1462.   mov    dx,3DEh
  1463.   out    dx,ax
  1464.   sti
  1465.   pop    dx ax
  1466.   ret
  1467.  
  1468. _paradise:                ; Paradise
  1469.   push    ax dx
  1470.   cli
  1471.   mov    [curBank],ax
  1472.   mov   dx,3CEh
  1473.   mov    ah,al
  1474.   shl   ah,4                    ; 64K bank number -> 4K bank number
  1475.   mov   al,09h                  ; program PR0A
  1476.   out    dx,ax
  1477.   mov   al,0Ah                  ; program PR0B
  1478.   out   dx,ax
  1479.   sti
  1480.   pop    dx ax
  1481.   ret
  1482.  
  1483. _trident:                ; Trident
  1484.   push    ax dx ax
  1485.   cli
  1486.   mov    [curBank],ax
  1487.   mov    dx,3CEh            ; set pagesize to 64k
  1488.   mov    al,6
  1489.   out    dx,al
  1490.   inc    dl
  1491.   in    al,dx
  1492.   dec    dl
  1493.   or    al,4
  1494.   mov    ah,al
  1495.   mov    al,6
  1496.   out    dx,ax
  1497.  
  1498.   mov    dl,0C4h            ; switch to BPS mode
  1499.   mov    al,0Bh
  1500.   out    dx,al
  1501.   inc    dl
  1502.   in    al,dx
  1503.   dec    dl
  1504.  
  1505.   pop    ax
  1506.   mov    ah,al
  1507.   xor    ah,2
  1508.   mov    dx,3C4h
  1509.   mov    al,0Eh
  1510.   out    dx,ax
  1511.   sti
  1512.   pop    dx ax
  1513.   ret
  1514.  
  1515. _tseng:                    ; Tseng
  1516.   push    ax dx
  1517.   cli
  1518.   mov    [curBank],ax
  1519.   and    al,7
  1520.   mov    ah,al
  1521.   shl    al,3
  1522.   or    al,ah
  1523.   or    al,01000000b
  1524.   mov    dx,3CDh
  1525.   out    dx,al
  1526.   sti
  1527.   pop    dx ax
  1528.   ret
  1529.  
  1530. _tseng4:                ; Tseng 4000 series
  1531. ;  push  ax dx
  1532. ;  cli
  1533. ;  mov   [curBank],ax
  1534. ;  mov   ah,al
  1535. ;  mov   dx,3BFh                 ; enable access to extended registers
  1536. ;  mov   al,3
  1537. ;  out   dx,al
  1538. ;  mov   dl,0D8h
  1539. ;  mov   al,0A0h
  1540. ;  out   dx,al
  1541. ;  and   ah,15
  1542. ;  mov   al,ah
  1543. ;  shl   al,4
  1544. ;  or    al,ah
  1545. ;  mov   dl,0CDh
  1546. ;  out   dx,al
  1547. ;  sti
  1548. ;  pop   dx ax
  1549. ;  ret
  1550.   push  ax dx
  1551.   cli
  1552.   mov   [curBank],ax
  1553.   and   al,0Fh
  1554.   mov   ah,al
  1555.   shl   ah,4
  1556.   or    al,ah
  1557.   mov   dx,3CDh
  1558.   out   dx,al
  1559.   sti
  1560.   pop   dx ax
  1561.   ret
  1562.  
  1563. _video7:                ; Video 7
  1564.   push    ax dx cx
  1565.   cli
  1566.   mov    [curBank],ax
  1567.   and    ax,15
  1568.   mov    ch,al
  1569.   mov    dx,3C4h
  1570.   mov    ax,0EA06h
  1571.   out    dx,ax
  1572.   mov    ah,ch
  1573.   and    ah,1
  1574.   mov    al,0F9h
  1575.   out    dx,ax
  1576.   mov    al,ch
  1577.   and    al,1100b
  1578.   mov    ah,al
  1579.   shr    ah,2
  1580.   or    ah,al
  1581.   mov    al,0F6h
  1582.   out    dx,al
  1583.   inc    dx
  1584.   in    al,dx
  1585.   dec    dx
  1586.   and    al,NOT 1111b
  1587.   or    ah,al
  1588.   mov    al,0F6h
  1589.   out    dx,ax
  1590.   mov    ah,ch
  1591.   mov    cl,4
  1592.   shl    ah,cl
  1593.   and    ah,100000b
  1594.   mov    dl,0CCh
  1595.   in    al,dx
  1596.   mov    dl,0C2h
  1597.   and    al,NOT 100000b
  1598.   or    al,ah
  1599.   out    dx,al
  1600.   sti
  1601.   pop    cx dx ax
  1602.   ret
  1603.  
  1604. _vesa:                ; Vesa SVGA interface
  1605.   push    ax bx dx
  1606.   cli
  1607.   mov    [curBank],ax
  1608.   mov    dx,ax
  1609.   xor    bx,bx
  1610.   mov    ax,4F05h
  1611.   int    10h
  1612.   sti
  1613.   pop    dx bx ax
  1614.   ret
  1615.  
  1616. _nobank:
  1617.   cli
  1618.   mov    [curBank],ax
  1619.   sti
  1620.   ret
  1621.  
  1622.  
  1623. MACRO    BKADR    func
  1624.   mov    [func],1
  1625.   mov    [bankadr],OFFSET _&func
  1626. ENDM
  1627.  
  1628. MACRO    NOJMP
  1629.   local    lbl
  1630.   jmp    short    lbl
  1631.     lbl:
  1632. ENDM
  1633.  
  1634.  
  1635. PROC    whichVGA    NEAR
  1636.   push    si di
  1637.  
  1638.   cmp    [inited],1
  1639.   jne    @@goTest
  1640.   mov    ax,[retval]
  1641.   pop    di si
  1642.   ret
  1643.  
  1644.     @@goTest:
  1645.   mov    [bankadr],OFFSET _nobank         ; Initialize variables
  1646.   mov    [vgamem],256
  1647.   mov    [bksize],64
  1648.   xor    ax,ax
  1649.   mov    [curBank],ax
  1650.   mov    [acumos],ax
  1651.   mov    [aheada],ax
  1652.   mov    [aheadb],ax
  1653.   mov    [ativga],ax
  1654.   mov    [chipstech],ax
  1655.   mov    [cirrus],ax
  1656.   mov    [compaq],ax
  1657.   mov    [everex],ax
  1658.   mov    [genoa],ax
  1659.   mov    [ncr],ax
  1660.   mov    [oak067],ax
  1661.   mov    [paradise],ax
  1662.   mov    [trident],ax
  1663.   mov    [t8900],ax
  1664.   mov    [tseng],ax
  1665.   mov    [tseng4],ax
  1666.   mov    [video7],ax
  1667.   mov    [vesa],ax
  1668.  
  1669.   mov    si,1                ; success code; changed on error
  1670.  
  1671.   mov    ax,cs                ; Test for VESA
  1672.   mov    es,ax
  1673.   mov    di,OFFSET vesabuf
  1674.   mov    ax,4F00h
  1675.   int    10h
  1676.   cmp    ax,004Fh
  1677.   jne    @@noVESA
  1678.   BKADR    vesa
  1679.   mov    [bksize],64            ; assume 64 K bank size (for now)
  1680.   mov    [vgamem],512            ; assume 512 K if VESA
  1681.   jmp    @@fini
  1682.  
  1683.     @@noVESA:
  1684.   mov    ax,0C000h            ; Test for ATI
  1685.   mov    es,ax
  1686.   cmp    [word ptr es:40h],'13'    ; ATI Signiture on the Video BIOS
  1687.   jnz    @@noATI
  1688.   BKADR    ativga
  1689.   mov    [bksize],64        ; 64K bank size
  1690.   mov    dx,[es:10h]        ; get value of ATI extended register
  1691.   mov    bl,[es:43h]        ; get value of ATI chip version
  1692.   cmp    bl,'3'
  1693.   jae    @@v6up            ; use different method to find memory size
  1694.   mov    al,0BBh
  1695.   cli
  1696.   out    dx,al
  1697.   inc    dx
  1698.   in    al,dx
  1699.   sti
  1700.   test    al,20h
  1701.   jz    @@no512
  1702.   mov    [vgamem],512
  1703.   jmp    short    @@no512
  1704.     @@v6up:
  1705.   mov    al,0B0h            ; method for newer ATIs
  1706.   cli
  1707.   out    dx,al
  1708.   inc    dx
  1709.   in    al,dx            ; get RAM size for versions 3-5
  1710.   sti
  1711.   test    al,10h            ; check if 256 K or 512 K
  1712.   jz    @@v7up
  1713.   mov    [vgamem],512
  1714.       @@v7up:
  1715.   cmp    bl,'4'            ; get RAM size for versions 4 & 5
  1716.   jb    @@no512
  1717.   test    al,8            ; check if version 5 chip has 1024 K
  1718.   jz    @@no512
  1719.   mov    [vgamem],1024
  1720.       @@no512:
  1721.   jmp    @@fini
  1722.  
  1723.     @@noATI:
  1724.   mov    ax,7000h            ; Test for Everex
  1725.   xor    bx,bx
  1726.   cld
  1727.   int    10h
  1728.   cmp    al,70h
  1729.   jnz    @@noEverex
  1730.   BKADR    everex
  1731.   mov    [bksize],64        ; 64 K bank size
  1732.   and    ch,11000000b        ; how much memory on board?
  1733.   jz    @@skp
  1734.   mov    [vgamem],512
  1735.      @@skp:            ; fall through for Everex boards using Trident or Tseng4000
  1736.  
  1737.     @@noEverex:
  1738.   mov    ax,0BF03h            ; Test for Compaq
  1739.   xor    bx,bx
  1740.   mov    cx,bx
  1741.   int    10h
  1742.   cmp    ax,0BF03h
  1743.   jnz    @@noCompaq
  1744.   test    cl,40h            ; is 640x480x256 available?
  1745.   jz    @@noCompaq
  1746.   BKADR    compaq
  1747.   mov    [bksize],4              ; 4 K bank size
  1748.   mov    [vgamem],512
  1749.   jmp    @@fini
  1750.  
  1751.     @@noCompaq:
  1752.   mov    dx,3C4h                ; Test for NCR 77C22E
  1753.   mov    ax,0FF05h
  1754.   call    _isport2
  1755.   jnz    @@noNCR
  1756.   mov    ax,5                   ; Disable extended registers
  1757.   out    dx,ax
  1758.   mov    ax,0FF10h        ; Try to write to extended register 10
  1759.   call    _isport2        ; If it writes then not NCR
  1760.   jz    @@noNCR
  1761.   mov    ax,105h            ; Enable extended registers
  1762.   out    dx,ax
  1763.   mov    ax,0FF10h
  1764.   call    _isport2
  1765.   jnz    @@noNCR            ; If it does NOT write then not NCR
  1766.   BKADR    ncr
  1767.   mov    [bksize],16        ; 16 K bank size
  1768.   mov    [vgamem],512
  1769.   jmp    @@fini
  1770.  
  1771.     @@noNCR:
  1772.   mov    dx,3C4h                ; Test for Trident
  1773.   mov    al,0Eh            ; Read mode control register #1
  1774.   out    dx,al
  1775.   inc    dx
  1776.   in    al,dx            ; Read old value
  1777.   xor    al,2
  1778.   push    ax
  1779.   xor    al,al            ; Write new value bit 1=0, all other bits=0
  1780.   out    dx,al
  1781.   in    al,dx            ; Read new value
  1782.   and    al,0Fh
  1783.   cmp    al,2            ; Check for Trident
  1784.   pop    ax            ; Old value in AX
  1785.   out    dx,al            ; Restore old value
  1786.   jne    @@noTrident
  1787.  
  1788.   BKADR    trident            ; Trident found
  1789.   mov    [bksize],64
  1790.  
  1791.   dec    dx            ; Distinguish 8800/8900
  1792.   mov    al,0Bh            ; Index of version register
  1793.   out    dx,al            ; Select version register
  1794.   inc    dx
  1795.   xor    al,al
  1796.   out    dx,al            ; Dummy write to force old definitions
  1797.   in    al,dx            ; Read causes new definitions
  1798.   cmp    al,3            ; Is it 8900+?
  1799.   jb    @@Trident8800        ; no, 8800
  1800.   mov    [t8900],1        ; yes
  1801.   mov    dx,3D5h
  1802.   mov    al,1Fh
  1803.   out    dx,al
  1804.   inc    dx
  1805.   in    al,dx
  1806.   and    al,3
  1807.   cmp    al,1
  1808.   jb    @@noTmem
  1809.   mov    [vgamem],512
  1810.   je    @@noTmem
  1811.   mov    [vgamem],1024
  1812.     @@noTmem:
  1813.   jmp    @@fini
  1814.         @@Trident8800:
  1815.   mov    [vgamem],512
  1816.   jmp    @@fini
  1817.  
  1818.         @@noTrident:
  1819.   mov    ax,6F00h            ; Test for Video 7
  1820.   xor    bx,bx
  1821.   cld
  1822.   int    10h
  1823.   cmp    bx,'V7'
  1824.   jnz    @@noVideo7
  1825.   BKADR    video7
  1826.   mov    [bksize],64        ; 64 K bank size
  1827.   mov    ax,6F07h
  1828.   cld
  1829.   int    10h
  1830.   and    ah,7Fh
  1831.   cmp    ah,1
  1832.   jbe    @@skp2
  1833.   mov    [vgamem],512
  1834.     @@skp2:
  1835.   cmp    ah,3
  1836.   jbe    @@skp3
  1837.   mov    [vgamem],1024
  1838.     @@skp3:
  1839.   jmp    @@fini
  1840.  
  1841.     @@noVideo7:
  1842.   mov    dx,3D4h                ; Test for GENOA GVGA
  1843.   mov    ax,032Eh        ; check for Herchi Register
  1844.   call    _isport2
  1845.   jnz    @@noGenoa
  1846.   mov    dx,3C4h            ; check for memory segment register
  1847.   mov    ax,3F06h
  1848.   call    _isport2
  1849.   jnz    @@noGenoa
  1850.   BKADR    genoa
  1851.   mov    [bksize],64        ; 64 K bank size
  1852.   mov    [vgamem],512
  1853.   jmp    @@fini
  1854.  
  1855.     @@noGenoa:
  1856.   call    cirrusDetect                ; Test for Cirrus
  1857.   cmp    [cirrus],0
  1858.   je    @@noCirrus
  1859.   jmp    @@fini
  1860.  
  1861.     @@noCirrus:
  1862.   mov    dx,3CEh                ; Test for Paradise
  1863.   mov    al,9            ; check Bank switch register
  1864.   out    dx,al
  1865.   inc    dx
  1866.   in    al,dx
  1867.   dec    dx
  1868.   or    al,al
  1869.   jnz    @@noParadise
  1870.  
  1871.   mov    ax,50Fh            ; turn off write protect on VGA registers
  1872.   out    dx,ax
  1873.   mov    dx,OFFSET _paradise
  1874.   mov    cx,1
  1875.   call    _chkbk
  1876.   jc    @@noParadise        ; if bank 0 and 1 same not paradise
  1877.   BKADR    paradise
  1878. ;  mov   [bksize],4              ; 4 K bank size
  1879.   mov   [bksize],64
  1880.  
  1881.   ; Disable write-protect of VGA registers
  1882.   mov    ax,050Fh
  1883.   mov    dx,3CEh
  1884.   out    dx,ax
  1885.   ; Unlock extended sequencer registers
  1886.   mov    ax,4806h
  1887.   mov    dx,3C4h
  1888.   out    dx,ax
  1889.   ; Enable access to PR10-17
  1890.   mov    ax,8529h
  1891.   mov    dx,3D4h
  1892.   out    dx,ax
  1893.   ; Allow access to all SVGA memory
  1894.   mov   dx,3D4h
  1895.   mov    al,2Fh
  1896.   out    dx,al
  1897.   inc    dx
  1898.   in    al,dx
  1899.   and    al,NOT 2
  1900.   out    dx,al
  1901.   ; Enable PR0A and PR0B
  1902.   mov   dx,3CEh
  1903.   mov   al,0Bh
  1904.   out   dx,al
  1905.   inc   dx
  1906.   in    al,dx
  1907.   and   al,NOT 8
  1908.   or    al,8
  1909.   out   dx,al
  1910.   ; Set PR0A for read, PR0B for write
  1911.   mov   dx,3C4h
  1912.   mov   al,11h
  1913.   out   dx,al
  1914.   inc   dx
  1915.   in    al,dx
  1916.   and   al,NOT 80h
  1917.   or    al,80h
  1918.   out   dx,al
  1919.  
  1920.   mov  dx,3CEh
  1921.   mov  al,0Bh                  ; 512k detect from
  1922.   out  dx,al
  1923.   inc  dx
  1924.   in   al,dx
  1925.   test al,80h                  ; if top bit set then 512k
  1926.   jz   @@nop512
  1927.   mov  [vgamem],512
  1928.        @@nop512:
  1929.   jmp  @@fini
  1930.  
  1931.     @@noParadise:
  1932.   mov    ax,5F00h            ; Test for Chips & Tech
  1933.   xor    bx,bx
  1934.   cld
  1935.   int    10h
  1936.   cmp    al,5Fh
  1937.   jnz    @@noChipsTech
  1938.   BKADR    chipstech
  1939.   mov    [bksize],16        ; 16 K bank size
  1940.   cmp    bh,1
  1941.   jb    @@skp4
  1942.   mov    [vgamem],512
  1943.   cmp    bh,2
  1944.   jb    @@skp4
  1945.   mov    [vgamem],1024
  1946.     @@skp4:
  1947.   jmp    @@fini
  1948.  
  1949.     @@noChipsTech:
  1950.   xor    ch,ch                ; check for Tseng 4000 series
  1951.   mov    dx,3D4h
  1952.   mov    ax,0F33h
  1953.   call    _isport2
  1954.   jnz    @@noTseng4
  1955.   mov    ch,1
  1956.  
  1957.   mov    dx,3BFh            ; Enable access to extended registers
  1958.   mov    al,3
  1959.   out    dx,al
  1960.   mov    dx,3D8h
  1961.   mov    al,0A0h
  1962.   out    dx,al
  1963.   jmp    short @@yes4
  1964.  
  1965.     @@noTseng4:
  1966.   mov    dx,3D4h                ; Test for Tseng 3000 or 4000
  1967.   mov    ax,1F25h        ; is the Overflow High register there?
  1968.   call    _isport2
  1969.   jnz    @@noTseng
  1970.   mov    al,03Fh            ; bottom six bits only
  1971.   jmp    short @@yes3
  1972.     @@yes4:
  1973.   mov    al,0FFh
  1974.     @@yes3:
  1975.   mov    dx,3CDh            ; test bank switch register
  1976.   call    _isport1
  1977.   jnz    @@noTseng
  1978.   BKADR    tseng
  1979.   mov    [bksize],64        ; 64 K bank size
  1980.   or    ch,ch
  1981.   jnz    @@t4mem
  1982.   mov    [vgamem],512
  1983.   jmp    @@fini
  1984.  
  1985.     @@t4mem:
  1986.   mov    dx,3D4h            ; Tseng 4000 memory detect 1meg
  1987.   mov    al,37h
  1988.   out    dx,al
  1989.   inc    dx
  1990.   in    al,dx
  1991.   test    al,1000b        ; if using 64kx4 RAMs then no more than 256k
  1992.   jz    @@nomem
  1993.   and    al,3
  1994.   cmp    al,1            ; if 8 bit wide bus then only two 256kx4 RAMs
  1995.   jbe    @@nomem
  1996.   mov    [vgamem],512
  1997.   cmp    al,2            ; if 16 bit wide bus then four 256kx4 RAMs
  1998.   je    @@nomem
  1999.   mov    [vgamem],1024        ; full meg with eight 256kx4 RAMs
  2000.     @@nomem:
  2001.   ; Special setup for ET4000
  2002.   mov   dx,3BFh
  2003.   mov   al,3
  2004.   out   dx,al
  2005.   mov   dl,0D8h
  2006.   mov   al,0A0h
  2007.   out   dx,al
  2008.   BKADR tseng4
  2009.  
  2010.   jmp    @@fini
  2011.  
  2012.     @@noTseng:
  2013.   mov    dx,3CEh                ; Test for Above A or B chipsets
  2014.   mov    ax,200Fh
  2015.   out    dx,ax
  2016.   inc    dx
  2017.   NOJMP
  2018.   in    al,dx
  2019.   cmp    al,21h
  2020.   jz    @@verB
  2021.   cmp    al,20h
  2022.   jnz    @@noAbove
  2023.   BKADR    aheada
  2024.   mov    [bksize],64        ; 64 K bank size
  2025.   mov    [vgamem],512
  2026.   jmp    @@fini
  2027.     @@verB:
  2028.   BKADR    aheadb
  2029.   mov    [bksize],64        ; 64 K bank size
  2030.   mov    [vgamem],512
  2031.   jmp   @@fini
  2032.  
  2033.     @@noAbove:
  2034.   mov    dx,3C4h                ; Test for AcuMos chipsets
  2035.   mov    ax,0006h
  2036.   out    dx,ax
  2037.   mov    ax,0FF09h
  2038.   call    _isport2           ; is scratchpad at index 9 writeable?
  2039.   jz    @@noAcumos
  2040.   mov    ax,0FF0Ah
  2041.   call    _isport2        ; is scratchpad at index 10 writeable?
  2042.   jz    @@noAcumos
  2043.   mov    ax,1206h
  2044.   out    dx,ax
  2045.   mov    ax,0FF09h
  2046.   call    _isport2
  2047.   jnz    @@noAcumos
  2048.   mov    ax,0FF0Ah
  2049.   call    _isport2
  2050.   jnz    @@noAcumos
  2051.   mov    dx,OFFSET _acumos
  2052.   mov    cx,1
  2053.   call    _chkbk
  2054.   jc    @@noAcumos
  2055.   BKADR    acumos
  2056.   mov    [bksize],4        ; 4 K bank size
  2057.   mov    dx,3C4h
  2058.   mov    al,0Ah
  2059.   out    dx,al
  2060.   inc     dx
  2061.   in    al,dx
  2062.   and    al,3
  2063.   cmp    al,1
  2064.   jb    @@noAcumosMem
  2065.   mov    [vgamem],512
  2066.   cmp    al,2
  2067.   jb    @@noAcumosMem
  2068.   mov    [vgamem],1024
  2069.   cmp    al,3
  2070.   jb    @@noAcumosMem
  2071.   mov    [vgamem],2048
  2072.       @@noAcumosMem:
  2073.   jmp    short    @@fini
  2074.  
  2075.     @@noAcumos:
  2076.   mov    dx,3DEh                ; Test for Oak Technology
  2077.   mov    ax,0FF11h        ; look for bank switch register
  2078.   call    _isport2
  2079.   jnz    @@fini
  2080.   BKADR    oak067
  2081.   mov    [bksize],64        ; 64 K bank size
  2082.   mov    al,0Dh
  2083.   out    dx,al
  2084.   inc    dx
  2085.   NOJMP
  2086.   in    al,dx
  2087.   test    al,11000000b
  2088.   jz    @@fini
  2089.   mov    [vgamem],512
  2090.   test    al,01000000b
  2091.   jz    @@fini
  2092.   mov    [vgamem],1024
  2093.   jmp    short    @@fini
  2094.  
  2095.       @@noSVGA:
  2096.   xor    si,si                ; set error flag
  2097.  
  2098.     @@fini:
  2099.   mov    ax,si                ; success code in AX for return
  2100.   mov    [retval],ax
  2101.   pop    di si
  2102.   ret
  2103. ENDP
  2104.  
  2105.  
  2106. PROC    cirrusDetect    NEAR
  2107.   mov    dx,3D4h            ; assume 3dx addressing
  2108.   mov    al,0Ch            ; screen a start address hi
  2109.   out    dx,al            ; select index
  2110.   inc    dx            ; point to data
  2111.   mov    ah,al            ; save index in ah
  2112.   in    al,dx            ; get screen a start address hi
  2113.   xchg    ah,al            ; swap index and data
  2114.   push    ax            ; save old value
  2115.   push    dx            ; save crtc address
  2116.   xor    al,al            ; clear crc
  2117.   out    dx,al            ; and out to the crtc
  2118.  
  2119.   mov    al,1Fh            ; Eagle ID register
  2120.   dec    dx            ; back    to index
  2121.   out    dx,al            ; select index
  2122.   inc    dx            ; point to data
  2123.   in    al,dx            ; read the id register
  2124.   mov    bh,al            ; and save it in bh
  2125.  
  2126.   mov    cl,4            ; nibble swap rotate count
  2127.   mov    dx,3C4h            ; sequencer/extensions
  2128.   mov    bl,6            ; extensions enable register
  2129.  
  2130.   ror    bh,cl            ; compute extensions disable value
  2131.   mov    ax,bx            ; extensions disable
  2132.   out    dx,ax            ; disable extensions
  2133.   inc    dx            ; point to data
  2134.   in    al,dx            ; read enable flag
  2135.   or    al,al            ; disabled ?
  2136.   jnz   @@Exit            ; nope, not an cirrus
  2137.  
  2138.   ror    bh,cl            ; compute extensions enable value
  2139.   dec    dx            ; point to index
  2140.   mov    ax,bx            ; extensions enable
  2141.   out    dx,ax            ; enable extensions
  2142.   inc    dx            ; point to data
  2143.   in    al,dx            ; read enable flag
  2144.   cmp    al,1            ; enabled ?
  2145.   jne    @@Exit            ; nope, not a Cirrus
  2146.  
  2147.   mov    dx,3C4h            ; Cirrus found -- get size of memory
  2148.   mov    al,0Fh
  2149.   out    dx,al
  2150.   inc    dx
  2151.   in    al,dx
  2152.   shr    al,3
  2153.   and    al,3
  2154.   cmp    al,1
  2155.   jb    @@Exit            ; only 256 K
  2156.   mov    [vgamem],512
  2157.   cmp    al,2
  2158.   jb    @@Setup            ; 512 K
  2159.   mov    [vgamem],1024        ; 1 meg
  2160.  
  2161.       @@Setup:
  2162.   mov    [cirrus],1
  2163.   BKADR    cirrus
  2164.   mov    [bksize],4
  2165.  
  2166.     @@Exit:
  2167.   pop    dx            ; restore crtc address
  2168.   dec    dx            ; point to index
  2169.   pop    ax            ; recover crc index and data
  2170.   out    dx,ax            ; restore crc value
  2171.   ret
  2172. ENDP
  2173.  
  2174.  
  2175. PROC    _chkbk    NEAR            ; bank switch check routine
  2176.   mov    di,0B800h
  2177.   mov    es,di
  2178.   xor    di,di
  2179.   mov    bx,1234h
  2180.   call    _gochk
  2181.   jnz    @@badchk
  2182.   mov    bx,4321h
  2183.   call    _gochk
  2184.   jnz    @@badchk
  2185.   clc
  2186.   ret
  2187.     @@badchk:
  2188.   stc
  2189.   ret
  2190. ENDP
  2191.  
  2192.  
  2193. PROC    _gochk    NEAR
  2194.   push    si
  2195.   mov    si,bx
  2196.  
  2197.   mov    al,cl
  2198.   call    dx
  2199.   xchg    bl,[es:di]
  2200.   mov    al,ch
  2201.   call    dx
  2202.   xchg    bh,[es:di]
  2203.  
  2204.   xchg    si,bx
  2205.  
  2206.   mov    al,cl
  2207.   call    dx
  2208.   xor    bl,[es:di]
  2209.   mov    al,ch
  2210.   call    dx
  2211.   xor    bh,[es:di]
  2212.  
  2213.   xchg    si,bx
  2214.  
  2215.   mov    al,ch
  2216.   call    dx
  2217.   mov    [es:di],bh
  2218.   mov    al,cl
  2219.   call    dx
  2220.   mov    [es:di],bl
  2221.  
  2222.   xor    al,al
  2223.   call    dx
  2224.   or    si,si
  2225.   pop    si
  2226.   ret
  2227. ENDP
  2228.  
  2229.  
  2230. PROC    _isport2    NEAR        ; check for valid I/O port
  2231.                     ; AL is index, AH is bit mask
  2232.   push    bx
  2233.   mov    bx,ax
  2234.   out    dx,al
  2235.   mov    ah,al
  2236.   inc    dx
  2237.   in    al,dx
  2238.   dec    dx
  2239.   xchg    al,ah
  2240.   push    ax
  2241.   mov    ax,bx
  2242.   out    dx,ax
  2243.   out    dx,al
  2244.   mov    ah,al
  2245.   inc    dx
  2246.   in    al,dx
  2247.   dec    dx
  2248.   and    al,bh
  2249.   cmp    al,bh
  2250.   jnz    @@noport
  2251.   mov    al,ah
  2252.   xor    ah,ah
  2253.   out    dx,ax
  2254.   out    dx,al
  2255.   mov    ah,al
  2256.   inc    dx
  2257.   in    al,dx
  2258.   dec    dx
  2259.   and    al,bh
  2260.   cmp    al,0
  2261.     @@noport:
  2262.   pop    ax
  2263.   out    dx,ax
  2264.   pop    bx
  2265.   ret
  2266. ENDP
  2267.  
  2268.  
  2269. PROC    _isport1    NEAR        ; check for valid I/O port
  2270.                     ; AL is bit mask
  2271.   mov    ah,al
  2272.   in    al,dx
  2273.   push    ax
  2274.   mov    al,ah
  2275.   out    dx,al
  2276.   in    al,dx
  2277.   and    al,ah
  2278.   cmp    al,ah
  2279.   jnz    @@noport
  2280.   xor    al,al
  2281.   out    dx,al
  2282.   in    al,dx
  2283.   and    al,ah
  2284.   cmp    al,0
  2285.     @@noport:
  2286.   pop    ax
  2287.   out    dx,al
  2288.   ret
  2289. ENDP
  2290.  
  2291.  
  2292. PROC    setMode    NEAR            ; Set 640x480x256
  2293.   mov   [scanline],SCREEN_WIDE
  2294.  
  2295.   cmp    [vesa],0
  2296.   jz    @@noVESA
  2297.   mov    bx,101h
  2298.   call    VESAset
  2299.   or    ax,ax                ; was function successful?
  2300. JUMPS
  2301.   jz    @@noSVGA            ; no, quit
  2302. NOJUMPS
  2303.   jmp    @@godo2
  2304.       @@noVESA:
  2305.   cmp    [compaq],0
  2306.   jz    @@noCompaq
  2307.   mov    [scanline],1024
  2308.   mov    ax,2Eh
  2309.   jmp    @@godo
  2310.     @@noCompaq:
  2311.   cmp    [genoa],0
  2312.   jz    @@noGenoa
  2313.   mov    ax,5Ch
  2314.   jmp    @@godo
  2315.     @@noGenoa:
  2316.   cmp    [ncr],0
  2317.   jz    @@noNCR
  2318.   mov    ax,5Fh
  2319.   jmp    @@godo
  2320.     @@noNCR:
  2321.   cmp    [oak067],0
  2322.   jz    @@noOak067
  2323.   mov    ax,53h
  2324.   jmp    @@godo
  2325.     @@noOak067:
  2326.   cmp    [aheada],0
  2327.   jnz    @@
  2328.   cmp    [aheadb],0
  2329.   jz    @@noAbove
  2330.     @@:
  2331.   mov    ax,61h
  2332.   jmp    @@godo
  2333.     @@noAbove:
  2334.   cmp    [everex],0
  2335.   jz    @@noEverex
  2336.   mov    ax,70h
  2337.   mov    bl,30h
  2338.   jmp    short @@godo
  2339.     @@noEverex:
  2340.   cmp    [ativga],0
  2341.   jz    @@noATI
  2342.   mov    ax,62h
  2343.   jmp    short @@godo
  2344.     @@noATI:
  2345.   cmp    [trident],0
  2346.   jz    @@noTrident
  2347.   mov    ax,5Dh
  2348.   jmp    short @@godo
  2349.     @@noTrident:
  2350.   cmp    [video7],0
  2351.   jz    @@noVideo7
  2352.   mov    ax,6F05h
  2353.   mov    bl,67h
  2354.   jmp    short @@godo
  2355.     @@noVideo7:
  2356.   cmp    [chipstech],0
  2357.   jz    @@noChipsTech
  2358.   mov    ax,79h
  2359.   jmp    short @@godo
  2360.     @@noChipsTech:
  2361.   cmp    [cirrus],0
  2362.   jz    @@noCirrus
  2363.   mov    ax,5Fh
  2364.   jmp    short    @@godo
  2365.       @@noCirrus:
  2366.   cmp    [acumos],0
  2367.   jnz    @@doParadise
  2368.   cmp    [paradise],0
  2369.   jz    @@noParadise
  2370.       @@doParadise:
  2371.   mov    ax,5Fh
  2372.   jmp    short    @@godo
  2373.     @@noParadise:
  2374.   cmp    [tseng],0
  2375.   jz    @@noSVGA
  2376.   mov    ax,2Eh
  2377.  
  2378.     @@godo:
  2379.   int    10h
  2380.       @@godo2:
  2381.   mov    [curBank],-1
  2382.   mov    ax,1                ; return success code
  2383.   ret
  2384.  
  2385.     @@noSVGA:
  2386.   xor    ax,ax                ; return error code
  2387.   ret
  2388. ENDP
  2389.  
  2390.  
  2391. PROC    VESAset        NEAR
  2392.   push    di
  2393.  
  2394.   push    bx
  2395.   mov    ax,4F02h
  2396.   int    10h                   ; set the mode
  2397.   pop    cx
  2398.   or    ah,ah                ; was function successful?
  2399.   jz    @@noError            ; yes
  2400.   xor    ax,ax                ; set error code (for setMode)
  2401.   jmp    short    @@Exit
  2402.  
  2403.       @@noError:
  2404.   mov    ax,cs
  2405.   mov    es,ax
  2406.   mov    di,OFFSET modebuf
  2407.   mov    ax,4F01h
  2408.   int    10h                ; get the mode information
  2409.   mov    ax,[modebuf.WinSize]
  2410.   mov    [bksize],ax
  2411.   mov    ax,[modebuf.BytesPerLine]
  2412.   mov    [scanline],ax
  2413.   mov    ax,1                ; set success code (for setMode)
  2414.  
  2415.       @@Exit:
  2416.   pop    di
  2417.   ret
  2418. ENDP
  2419.  
  2420.  
  2421. PROC    makeAddrTable    NEAR
  2422.   LOCAL    temp:WORD
  2423.   push    si di
  2424.  
  2425.   mov    si,OFFSET lineOffs
  2426.   mov    di,OFFSET bankNum
  2427.   xor    bx,bx                ; current line number = 0
  2428.  
  2429.   mov    ax,[bksize]            ; separate process if bksize=64 K
  2430.   cmp    ax,64
  2431.   je    @@64kBnk
  2432.  
  2433.   mov    cl,10
  2434.   shl    ax,cl                ; AX = bank size in bytes
  2435.   dec    ax
  2436.   mov    [temp],ax            ; [temp] = banksize in bytes - 1
  2437.   mov    ax,[bksize]            ; AX = bank size in K
  2438.     @@shlp:
  2439.   inc    cl
  2440.   shr    ax,1
  2441.   jnz    @@shlp                ; loop until AX = 0
  2442.   dec    cx
  2443.  
  2444.   xor    ax,ax                ; AX = 0
  2445.   xor    dx,dx                ; DX = 0
  2446.     @@lp:
  2447.   push    ax                ; store AX
  2448.   shr    ax,cl
  2449.   add    dx,ax                ; update current bank number
  2450.   pop    ax                ; restore AX
  2451.   and    ax,[temp]            ; mask offset so it's < bank size
  2452.   mov    [cs:si],ax            ; save line offset
  2453.   add    si,2                ; update pointer
  2454.   mov    [cs:di],dx            ; save bank number
  2455.   add    di,2                ; update pointer
  2456.   add    ax,[scanline]            ; update offset
  2457.   inc    bx                ; update line number
  2458.   cmp    bx,SCREEN_DEEP
  2459.   jb    @@lp                ; loop until all lines done
  2460.   jmp    short    @@calcBankChange    ; calculate bank change table
  2461.  
  2462.     @@64kBnk:
  2463.   xor    ax,ax                ; AX = 0
  2464.   xor    dx,dx                ; DX = 0
  2465.   mov    cx,[scanline]            ; CX = width of line in bytes
  2466.       @@nlp:
  2467.   mov    [cs:si],ax            ; store line offset
  2468.   add    si,2                ; update pointer
  2469.   mov    [cs:di],dx            ; store bank number
  2470.   add    di,2                ; update pointer
  2471.   add    ax,cx                ; add another line width
  2472.   adc    dx,0                ; increase bank number if overflow
  2473.   inc    bx                ; update current line number
  2474.   cmp    bx,SCREEN_DEEP
  2475.   jb    @@nlp                ; jump until all lines done
  2476.  
  2477.       @@calcBankChange:
  2478.   mov    di,OFFSET bankChanges        ; initialize pointer
  2479.   xor    ax,ax                ; AX = current line
  2480.       @@bankChangeLoop:
  2481.   mov    bx,ax                ; BX = current line
  2482.   shl    bx,1                ; to access a table of words
  2483.   mov    dx,[cs:bankNum+bx]        ; DX = bank at start of current line
  2484.   mov    bx,ax                ; BX = current line
  2485.   inc    bx                ; BX = next line
  2486.   shl    bx,1                ; to access a table of words
  2487.   mov    cx,[cs:bankNum+bx]        ; CX = bank at start of next line
  2488.   mov    si,[cs:lineOffs+bx]        ; SI = offset at start of next line
  2489.   or    si,si                ; is SI=0?
  2490.   jz    @@L1                ; yes, jump
  2491.   dec    cx                ; CX = bank at end of current line
  2492.       @@L1:
  2493.   cmp    cx,dx                ; are start and end banks the same?
  2494.   jne    @@newBank            ; bank changed, jump
  2495.   mov    [word ptr cs:di],1        ; store bank changed flag
  2496.   jmp    short    @@L2            ; jump
  2497.       @@newBank:
  2498.   mov    [word ptr cs:di],0        ; store bank same flag
  2499.       @@L2:
  2500.   add    di,2                ; update pointer
  2501.   inc    ax                ; update current line number
  2502.   cmp    ax,SCREEN_DEEP
  2503.   jb    @@bankChangeLoop        ; loop until all lines done
  2504.  
  2505.   pop    di si
  2506.   ret
  2507. ENDP
  2508.  
  2509.  
  2510.     ENDS
  2511.  
  2512. END
  2513.